﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace Djs.Tools.Tresor.Gui
{
    /// <summary>
    /// Knihovna extenzí vizuálních tříd a struktur
    /// </summary>
    public static class Extensions
    {
        #region Font
        /// <summary>
        /// Vrátí nový font vytvořený z this pouze změnou velikosti.
        /// Ratio má rozměr 1, takže font o 15% větší získáme zadáním ratio 1.15f: Font greater = original.CreateSimilar(1.15f);
        /// </summary>
        /// <param name="original"></param>
        /// <param name="ratio">Koeficient změny velikosti. 1.0f = beze změny. Výsledná velikost bude zarovnána do mezí EmSize = 5f - 84f.</param>
        /// <returns></returns>
        public static Font CreateSimilar(this Font original, float ratio) 
        { return _CreateSimilar(original, ratio, null, null, null, null); }
        /// <summary>
        /// Vrátí nový font vytvořený z this pouze změnou stylu.
        /// </summary>
        /// <param name="original"></param>
        /// <param name="style">Požadovaný styl písma</param>
        /// <returns></returns>
        public static Font CreateSimilar(this Font original, FontStyle style)
        { return _CreateSimilar(original, null, style, null, null, null); }
        /// <summary>
        /// Vrátí nový font vytvořený z this pouze změnou stylu.
        /// Lze zadat hodnoty Bold, Italic, Underline: null = nechá podle originálu, false nebo true zapne nebo vypne danou vlastnost.
        /// </summary>
        /// <param name="original"></param>
        /// <param name="style"></param>
        /// <param name="bold">null = beze změny, true/false = nastavit daný řez písma</param>
        /// <param name="italic">null = beze změny, true/false = nastavit daný řez písma</param>
        /// <param name="underline">null = beze změny, true/false = nastavit daný řez písma</param>
        public static Font CreateSimilar(this Font original, bool? bold, bool? italic, bool? underline)
        { return _CreateSimilar(original, null, null, bold, italic, underline); }
        /// <summary>
        /// Vrátí nový font vytvořený z this pouze změnou stylu.
        /// </summary>
        /// <param name="original"></param>
        /// <param name="ratio">Koeficient změny velikosti. 1.0f = beze změny. Výsledná velikost bude zarovnána do mezí EmSize = 5f - 84f.</param>
        /// <param name="style">Požadovaný styl písma</param>
        /// <returns></returns>
        public static Font CreateSimilar(this Font original, float ratio, FontStyle style)
        { return _CreateSimilar(original, ratio, style, null, null, null); }
        /// <summary>
        /// Vrátí nový font vytvořený z this pouze změnou stylu.
        /// Lze zadat hodnoty Bold, Italic, Underline: null = nechá podle originálu, false nebo true zapne nebo vypne danou vlastnost.
        /// </summary>
        /// <param name="original"></param>
        /// <param name="ratio">Koeficient změny velikosti. 1.0f = beze změny. Výsledná velikost bude zarovnána do mezí EmSize = 5f - 84f.</param>
        /// <param name="bold">null = beze změny, true/false = nastavit daný řez písma</param>
        /// <param name="italic">null = beze změny, true/false = nastavit daný řez písma</param>
        /// <param name="underline">null = beze změny, true/false = nastavit daný řez písma</param>
        /// <returns></returns>
        public static Font CreateSimilar(this Font original, float ratio, bool? bold, bool? italic, bool? underline)
        { return _CreateSimilar(original, ratio, null, bold, italic, underline); }
        /// <summary>
        /// Vrátí font podobný zadanému fontu.
        /// </summary>
        /// <param name="original"></param>
        /// <param name="ratio"></param>
        /// <param name="style"></param>
        /// <param name="bold"></param>
        /// <param name="italic"></param>
        /// <param name="underline"></param>
        /// <returns></returns>
        private static Font _CreateSimilar(Font original, float? ratio, FontStyle? style, bool? bold, bool? italic, bool? underline)
        {
            float newEmSize = (ratio.HasValue ? ratio.Value * original.Size : original.Size);
            newEmSize = (newEmSize < 5f ? 5f : (newEmSize > 84f ? 84f : newEmSize));

            FontStyle newStyle = original.Style;
            if (style.HasValue)
            {
                newStyle = style.Value;
            }
            else
            {
                bool isBold = (bold.HasValue ? bold.Value : original.Bold);
                bool isItalic = (italic.HasValue ? italic.Value : original.Italic);
                bool isUnderline = (underline.HasValue ? underline.Value : original.Underline);
                newStyle = (isBold ? FontStyle.Bold : FontStyle.Regular) |
                           (isItalic ? FontStyle.Italic : FontStyle.Regular) |
                           (isUnderline ? FontStyle.Underline : FontStyle.Regular);
            }
            return new Font(original.FontFamily, newEmSize, newStyle);
        }
        #endregion
    }
}
